#include "Projectile.h"
#include "XMLHelper.h"
#include "Physics.h"
#include "cScene.h"

Projectile::Projectile()
{
	m_velocityX = 0;
	m_velocityY = 0;
	mp_animations = new Animation[10];
	m_currentFrame = 0;
	GetCollider()->SetType(Collider::FRIENDLYPROJECTILE);
}

Projectile::Projectile(int x, int y, float vx, float vy)
{
	SetPosition(x, y);
	SetWidthHeight(18, 8);
	SetType(cBicho::PROJECTILE);
	m_velocityX = vx;
	m_velocityY = vy;
	mp_animations = new Animation[10];
	m_currentFrame = 0;
	LoadAnimations();
	SetState(STATE_FLYING);
	GetCollider()->SetType(Collider::FRIENDLYPROJECTILE);
}

Projectile::~Projectile()
{
	delete[] mp_animations;
}

void Projectile::GetVelocity(float * vx, float * vy)
{
	*vx = m_velocityX;
	*vy = m_velocityY;
}

void Projectile::SetVelocity(float vx, float vy)
{
	m_velocityX = vx;
	m_velocityY = vy;
}


void Projectile::Draw(int tex_id)
{
	float xo, yo, xf, yf;
	int w, h;

	switch (GetState())
	{
		//1
	case STATE_FLYING:
		xo = (float)mp_animations[1].GetFrame(0).first.first / 1124.0;
		yo = (float)mp_animations[1].GetFrame(0).first.second / 600.0;
		xf = (float)mp_animations[1].GetFrame(0).second.first / 1124.0;
		yf = (float)mp_animations[1].GetFrame(0).second.second / 600.0;
		GetFrameWidthHeight(&w, &h, 1);
		break;
	case STATE_EXPLODING:
		xo = (float)mp_animations[0].GetFrame(m_currentFrame).first.first / 1124.0;
		yo = (float)mp_animations[0].GetFrame(m_currentFrame).first.second / 600.0;
		xf = (float)mp_animations[0].GetFrame(m_currentFrame).second.first / 1124.0;
		yf = (float)mp_animations[0].GetFrame(m_currentFrame).second.second / 600.0;
		m_currentFrame = NextFrame(6);
		GetFrameWidthHeight(&w, &h, 0);
		break;
	}
	float alpha = atan(m_velocityY / m_velocityX);
	if (GetState() != STATE_READYFORDELETION)DrawRect(tex_id, xo, yo, xf, yf, w, h, m_velocityX< 0 ? alpha + 3.14159265359 : alpha);
}

void Projectile::GetFrameWidthHeight(int * w, int * h, int animation)
{
	*w = abs(mp_animations[animation].GetFrame(m_currentFrame).first.first - mp_animations[animation].GetFrame(m_currentFrame).second.first);
	*h = abs(mp_animations[animation].GetFrame(m_currentFrame).first.second - mp_animations[animation].GetFrame(m_currentFrame).second.second);
}

void Projectile::LoadAnimations()
{
	Animation animation;
	int x0, y0, xf, yf;
	XMLHelper helper;
	helper.Load("Assets\\animations.xml");
	char * frame;
	frame = (char *)malloc(sizeof(char)* 30);
	strcpy(frame, "animation/explosion/frame/");
	for (int i = 0; i < 6; ++i)
	{
		char * newFrame = (char *)malloc(sizeof(char)* 30);
		strcpy(newFrame, frame);
		char * frameNumber;
		frameNumber = (char *)malloc(sizeof(char)* 2);
		frameNumber[0] = '1' + i;
		frameNumber[1] = '\0';
		strcat(newFrame, frameNumber);
		x0 = std::atoi(helper.GetElement(newFrame).GetAttributeValue("positionX0").c_str());
		y0 = std::atoi(helper.GetElement(newFrame).GetAttributeValue("positionY0").c_str());
		xf = std::atoi(helper.GetElement(newFrame).GetAttributeValue("positionXF").c_str());
		yf = std::atoi(helper.GetElement(newFrame).GetAttributeValue("positionYF").c_str());
		mp_animations[0].AddFrame(x0, y0, xf, yf);
		free(frameNumber);
	}	
	free(frame);

	x0 = std::atoi(helper.GetElement("animation/projectile/frame/1").GetAttributeValue("positionX0").c_str());
	y0 = std::atoi(helper.GetElement("animation/projectile/frame/1").GetAttributeValue("positionY0").c_str());
	xf = std::atoi(helper.GetElement("animation/projectile/frame/1").GetAttributeValue("positionXF").c_str());
	yf = std::atoi(helper.GetElement("animation/projectile/frame/1").GetAttributeValue("positionYF").c_str());
	mp_animations[1].AddFrame(x0, y0, xf, yf);
}

void Projectile::Logic(Tile * map)
{
	switch (GetState())
	{
		case STATE_FLYING:
		{
			int x, y;
			GetPosition(&x, &y);
			int * coordinatesMap = map->GetCollider()->GetCoordinates();
			int tileSize = coordinatesMap[2] - coordinatesMap[0];
			if (x > SCENE_WIDTH*tileSize || x < 0 || y > SCENE_HEIGHT*tileSize || y < 0)
			{
				delete(coordinatesMap);
				SetState(STATE_READYFORDELETION);
			}
			else
			{
				delete(coordinatesMap);
				SetPosition(x + m_velocityX, y + m_velocityY);
				Tile * collidingTile = Physics::IsCollidingStatic(map, SCENE_WIDTH, SCENE_HEIGHT, GetCollider(), Physics::All);
				if (collidingTile)
				{
					SetPosition(x, y);
					SetState(STATE_EXPLODING);
				}
				Collider * collidingObject = Physics::IsCollidingDynamic(GetCollider(), Physics::All);
				if (collidingObject && (collidingObject->GetType()==Collider::ENEMY || collidingObject->GetType()==Collider::ENEMYPROJECTILE))
				{
					SetState(STATE_EXPLODING);
				}
			}
		}
		break;
		case STATE_EXPLODING:
			if (m_currentFrame == 5)
			{
				SetState(STATE_READYFORDELETION);
			}
			break;	
	}
}